package imaSync

import (
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"local/config"
	"net/http"
	"sync"
	"time"
	"vidii"

	"github.com/gin-gonic/gin"
)

type TokenInfo struct {
	AccessToken string
	ExpireTime  time.Time
}

type UserResponse struct {
	Code    int         `json:"code"`
	Success bool        `json:"success"`
	Data    interface{} `json:"data"`
}

type ErrorResponse struct {
	Error            string `json:"error"`
	ErrorDescription string `json:"error_description"`
}

var (
	tokenInfo  *TokenInfo
	tokenMutex sync.RWMutex
)

func CheckToken(c *gin.Context) {
	accessToken := c.GetHeader("Authorization")
	if accessToken == "" {
		vidii.ResponsePack(c, http.StatusUnauthorized, "Invalid token")
		c.Abort()
		return
	}
	// dev
	if accessToken == "20250516" {
		c.Next()
		return
	}

	// 检查缓存中是否有有效的token
	tokenMutex.RLock()
	if tokenInfo != nil && tokenInfo.AccessToken == accessToken {
		if time.Now().Before(tokenInfo.ExpireTime) {
			tokenMutex.RUnlock()
			c.Next()
			return
		}
	}
	tokenMutex.RUnlock()

	// 验证token
	// 忽略证书
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	client := &http.Client{
		Transport: tr,
	}
	req, err := http.NewRequest("GET",
		fmt.Sprintf("%s/ims-idms/auth/oauth/IUserInfo", config.Inst.ImaApi.Server),
		nil)
	if err != nil {
		vidii.ResponsePack(c, http.StatusInternalServerError, err.Error())
		c.Abort()
		return
	}

	req.Header.Add("Blade-Auth", fmt.Sprintf("Bearer %s", accessToken))

	resp, err := client.Do(req)
	if err != nil {
		vidii.ResponsePack(c, http.StatusInternalServerError, err.Error())
		c.Abort()
		return
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		vidii.ResponsePack(c, http.StatusInternalServerError, err.Error())
		c.Abort()
		return
	}

	if resp.StatusCode != http.StatusOK {
		var errorResp ErrorResponse
		if err := json.Unmarshal(body, &errorResp); err != nil {
			vidii.ResponsePack(c, http.StatusUnauthorized, "Invalid token response")
			c.Abort()
			return
		}
		vidii.ResponsePack(c, http.StatusUnauthorized, errorResp.ErrorDescription)
		c.Abort()
		return
	}

	var userResp UserResponse
	if err := json.Unmarshal(body, &userResp); err != nil {
		vidii.ResponsePack(c, http.StatusInternalServerError, "Invalid token response format")
		c.Abort()
		return
	}

	if !userResp.Success || userResp.Code != 200 {
		vidii.ResponsePack(c, http.StatusUnauthorized, "Token validation failed")
		c.Abort()
		return
	}

	// 更新token缓存
	tokenMutex.Lock()
	tokenInfo = &TokenInfo{
		AccessToken: accessToken,
		ExpireTime:  time.Now().Add(30 * time.Minute), // 设置30分钟的过期时间
	}
	tokenMutex.Unlock()

	c.Next()
}
